package com.chenyun.gateway.config.swagger;

import com.alibaba.fastjson2.JSON;
import com.chenyun.gateway.dynamic.DynamicGatewayRouteConfig;
import com.chenyun.gateway.vo.WhiteUrl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.List;

/**
 * 获取SwaggerResources列表信息，即业务模块列表
 * 列表数据填充在swagger ui左上角的下拉框里
 *
 * @author lonni
 * @Description:
 * @date 2020/11/2311:23
 */
@Configuration
@Primary
@Slf4j
public class MerdeSwaggerResourceProvider implements SwaggerResourcesProvider {
    public static final String API_URI = "v2/api-docs";

    /**
     * 当前路由的类型 static dynamic
     */
    @Value("${gateway.routes.type}")
    private String gatewayType;


    private final RouteLocator routeLocator;
    /**
     * 静态路由
     * 从appliccation.yml中解析前缀为spring.cloud.gateway的配置
     */
    private final GatewayProperties gatewayProperties;
    /**
     * 白名单的配置
     */
    private final WhiteUrl whiteUrl;

    /**
     * 动态路由
     */
    private final DynamicGatewayRouteConfig dynamicGatewayRouteConfig;

    public MerdeSwaggerResourceProvider(RouteLocator routeLocator,
                                        GatewayProperties gatewayProperties,
                                        DynamicGatewayRouteConfig dynamicGatewayRouteConfig,
                                        WhiteUrl whiteUrl
    ) {
        this.routeLocator = routeLocator;
        this.gatewayProperties = gatewayProperties;
        this.dynamicGatewayRouteConfig = dynamicGatewayRouteConfig;
        this.whiteUrl = whiteUrl;
    }

    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resourceList = new ArrayList<>();
        List<String> routes = new ArrayList<>();
        //从路由中拿到路由的id
        routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
        List<RouteDefinition> routeDefinitions = ("static").equals(gatewayType) ? gatewayProperties.getRoutes()
                : dynamicGatewayRouteConfig.getDynamicRouteList();
        //从网关配置中拿到路由且存在routes中的
        routeDefinitions.stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> {
//            final Optional<FilterDefinition> filterDefinitionOptional = route.getFilters().stream().filter(filterDefinition -> "StripPrefix".equalsIgnoreCase(filterDefinition.getName()))
//                    .findFirst();

            route.getPredicates().stream()
                    .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                    .forEach(predicateDefinition ->
                    {
                        log.info("predicateDefinition....{}", JSON.toJSONString(predicateDefinition));
                        //加入到列表 默认用id作为模块名  route.getId()
                        //这里修改为从metedata属性的name
                        String mudelName = route.getMetadata() == null || route.getMetadata().isEmpty() ? route.getId() : route.getMetadata().get("name").toString();
                        //拿到path
                        String path = predicateDefinition.getArgs().containsKey(NameUtils.GENERATED_NAME_PREFIX + "0") ?
                                predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0") :
                                predicateDefinition.getArgs().get("pattern");
//                        //判断是否含有截取前缀过滤器
//                        filterDefinitionOptional.ifPresent((p) -> {
//                            final String parts = p.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0");
//                            String newPath = "/" + (String) Arrays.stream(StringUtils.tokenizeToStringArray(path, "/")).skip(Long.parseLong(parts)).collect(Collectors.joining("/"));
//                            newPath = newPath + (newPath.length() > 1 && path.endsWith("/") ? "/" : "");
//                            log.info("routeName:{},path:{},newPath:{}",route.getId(),path,newPath);
//                        });

                        resourceList.add(
                                swaggerResource(mudelName, path.replace("**", API_URI)));
                        //增加服务的swagger路径到到白名单中
                        whiteUrl.addIgnorePath(path.replace("**", "v2/**"));

                    });
        });
        return resourceList;
    }

    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion("1.0");
        return swaggerResource;
    }

    public String getGatewayType() {
        return gatewayType;
    }

    public void setGatewayType(String gatewayType) {
        this.gatewayType = gatewayType;
    }
}
